# plotly_3d_state_values.py

import json
import plotly.graph_objs as go
import os

def load_evaluation_cache(cache_file='evaluation_cache.json'):
    """
    加载评估缓存数据。

    参数:
    - cache_file (str): 存储评估缓存的JSON文件路径。

    返回:
    - cache (dict): 键为超参数组合（JSON字符串），值为准确率。
    """
    if os.path.exists(cache_file):
        with open(cache_file, 'r') as f:
            cache = json.load(f)
        print(f"Loaded {len(cache)} hyperparameter configurations from {cache_file}.")
        return cache
    else:
        print(f"No evaluation cache found at {cache_file}.")
        return {}

def plot_interactive_3d_state_values(cache):
    """
    使用Plotly绘制交互式的状态-值函数3D散点图。

    参数:
    - cache (dict): 超参数组合到准确率的映射。

    返回:
    - None
    """
    if not cache:
        print("No data available to plot.")
        return

    # 提取超参数值和对应的准确率
    learning_rates = []
    max_depths = []
    n_estimators = []
    accuracies = []

    for params_str, acc in cache.items():
        params = json.loads(params_str)
        learning_rates.append(params['learning_rate'])
        max_depths.append(params['max_depth'])
        n_estimators.append(params['n_estimators'])
        accuracies.append(acc)

    # 创建Plotly散点图
    trace = go.Scatter3d(
        x=learning_rates,
        y=max_depths,
        z=n_estimators,
        mode='markers',
        marker=dict(
            size=5,
            color=accuracies,
            colorscale='Viridis',
            opacity=0.8,
            colorbar=dict(title='Validation Accuracy')
        ),
        text=[f'LR: {lr}, MD: {md}, NE: {ne}<br>Acc: {acc:.4f}' for lr, md, ne, acc in zip(learning_rates, max_depths, n_estimators, accuracies)],
        hoverinfo='text'
    )

    layout = go.Layout(
        title='Interactive State-Value Function: Validation Accuracy for Hyperparameter Configurations',
        scene=dict(
            xaxis=dict(title='Learning Rate'),
            yaxis=dict(title='Max Depth'),
            zaxis=dict(title='Number of Estimators')
        )
    )

    fig = go.Figure(data=[trace], layout=layout)
    fig.show()

if __name__ == "__main__":
    cache = load_evaluation_cache('evaluation_cache.json')
    plot_interactive_3d_state_values(cache)
